<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <script>
    const ArrayPrototype = Array.prototype;
    const arrProto = Object.create(ArrayPrototype);
    ['push', 'splice', 'slice', 'shift'].forEach(methods => {
      arrProto[methods] = function () {
        ArrayPrototype[methods].call(this, ...arguments)
        updateView()
      }
    })

    console.log("arrProto:", arrProto)
    function updateView() {
      console.log("视图更新了")
    }

    function definReactive(target, key, value) {
      observer(value)
      Object.defineProperty(target, key, {
        get() {
          return value
        },
        set(newV) {
          if (newV !== value) {
            observer(newV) // 更改对象视图
            value = newV // value一直在闭包环境中，再get也能获取到新的值
            updateView()
          }
        }
      })
    }



    function observer(target) {
      // 判断target不是对象，
      if (typeof target !== 'object' || target === null) {
        return target;
      }

      if (Array.isArray(target)) {

        target.__proto__ = arrProto
        console.log(arrProto)
      }

      for (let key in target) {
        definReactive(target, key, target[key])
      }
    }

    const data = {
      name: 'devin',
      age: '11',
      gender: 0,
      info: {
        address: 'sh'
      },
      list: [1, 2, 4, 5]
    }

    observer(data)

    data.name = 'hello world'
    // data.info.address = 'dddd'
    // data.info.address = 'sss'
    // data.info = { ...data.info, height: '175' }
    // data.info.height = '175'

    // data.list.push(1212)
    // delete data.name
    // console.log("Data:", data)
    // const data = {}
    // let name = '1711A';

    // Object.defineProperty(data, 'name', {
    //   get: function () {
    //     console.log('get')
    //     return name
    //   },
    //   set: function (newV) {
    //     console.log('set')
    //     name = newV
    //   }
    // })

    // data.name   // get
    // data.name = '要毕业了' // set
    // console.log('data:', data)
    // const data = {}
    // let name = '12323'
    // Object.defineProperty(data, 'name', {
    //   get() {
    //     console.log("get")
    //     return name
    //   },
    //   set(v) {
    //     console.log('set')
    //     name = v;
    //   }
    // })

    // data.name
    // data.name = '1801B'



  </script>
</body>

</html>
